home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / doc / mindy.doc < prev    next >
Encoding:
Text File  |  1995-03-15  |  43.4 KB  |  1,025 lines  |  [TEXT/ttxt]

  1. The Mindy Compiler and Interpreter
  2.  
  3. Copyright (c) 1994  Carnegie Mellon University
  4. All rights reserved.  Refer to the end of this document for precise terms of
  5. use. 
  6.  
  7. The Gwydion Project would like to thank those on the net that have
  8. contributed code patches and bug reports for Mindy:
  9.    Adam Alpern, Patrick Beard, Steve Strassman, Scott Collins, Ed Gamble,
  10.    Bruno Haible, John Shen, Galen Hunt, Richard Lynch, Dan Ratner, Court
  11.    Demas, Miles Bader, Kelly Murray, Nick Thompson
  12. Special thanks for a major effort to Roger Critchlow for enhancements to
  13. Mindy.
  14.  
  15.  
  16.  
  17. Introduction
  18.  
  19. Mindy is an implementation of a language that is very much like the language
  20. described in the Dylan(tm) Interim Reference Manual (DIRM).  The name
  21. "Mindy" is derived from "Mindy Is Not Dylan Yet", and as the name implies,
  22. Mindy is incomplete.  Mindy is incomplete for the following reasons:
  23.    1] We do not implement everything in the DIRM.
  24.    2] The DIRM does not specify all that Apple(tm) intends Dylan to be.
  25.    3] There's no way to validate what a Dylan implementation is, even if we
  26.       had a full specification. 
  27. However, Mindy does implement most of what we believe Dylan will be.
  28.  
  29. Mindy was developed by the Gwydion Project at Carnegie Mellon University for
  30. our own internal use as a development tool while we work on our "real"
  31. high-performance Dylan implementation.  We have decided to make Mindy
  32. available for other people who want to learn about Dylan.  However, the
  33. amount of effort that we can put into maintaining Mindy is strictly limited.
  34.  
  35. Mindy will never be an industrial-strength implementation, and nobody should
  36. depend on it for real work.  We will make future releases from time to time
  37. as we add new features and fix bugs, but this is strictly a sideshow for us.
  38. We would appreciate receiving bug reports (especially those accompanied by
  39. code patches) and suggestions for improvements, but we may not fix every bug
  40. reported in a timely manner, or fix it at all.  Our work on development of
  41. the "real" Gwydion/Dylan must take precedence.
  42.  
  43. We hope that nobody will draw any conclusions about the performance of our
  44. future Gwydion/Dylan compiler or the performance attainable in Dylan from
  45. experience using Mindy.  It's not designed to be fast.
  46.  
  47. Mindy comprises two C programs, a compiler that produces byte-codes and a
  48. byte-code interpreter.  Currently, building Mindy requires Gcc, Gmake, Flex,
  49. and Bison.  We do not distribute these.  If you do not have GNU tools, you
  50. can ftp them from:
  51.    prep.ai.mit.edu  in the directory pub/gnu
  52.  
  53. Instructions for compiling and installing Mindy can be found in the file
  54. INSTALL at the top level of the Mindy release.  We have built and tested
  55. Mindy under MACH on the DECstation and HP-UX on HP 700's.  We have built and
  56. run Mindy, but not tested it extensivly, under OSF1 on the Alpha and Irix on
  57. the SGI.
  58.  
  59.  
  60.  
  61. Hello, World
  62.  
  63. Well, the first program anyone should endeavor to write in a new language
  64. is, of course, Hello World.  Type this into a file called hw.dylan:
  65.  
  66.    module: dylan-user
  67.  
  68.    define method main (#rest ignore)
  69.      puts("Hello, World.\n");
  70.    end;
  71.  
  72. To compile your program invoke $INSTALL/bin/mc, for example: 
  73.  
  74.    % $INSTALL/bin/mc hw.dylan
  75.  
  76. This produces a file named "hw.dbc".  The .dbc stands for Dylan-byte-code.
  77. To run the program, say:
  78.  
  79.    % $INSTALL/bin/mindy -f hw.dbc
  80.  
  81. It should print "Hello, World." to standard output and then exit.  Fun, huh?
  82.  
  83.  
  84.  
  85. The Main Routine
  86.  
  87. After loading your program, Mindy invokes the generic function "main".  Your
  88. program must define a method for main, or Mindy will signal a "no applicable
  89. methods" error and put you in the debugger.  For more information on the
  90. main function, see Section The Extensions Module.
  91.  
  92. It can be useful to load code into Mindy with no main method.  Once you land
  93. in the debugger, you can call any function manually.  This provides a way to
  94. test any library.
  95.  
  96.  
  97.  
  98. Multiple Files
  99.  
  100. When working with a larger program, you will probably have more than one
  101. .dylan file.  In which case, you just compile them each independently, and
  102. then run Mindy with multiple -f switches:
  103.  
  104.    % mindy -f foo.dbc -f bar.dbc -f baz.dbc
  105.  
  106. Mindy loads the files specified with the -f switches in the order you
  107. specify the files on the command line.  This becomes important when you
  108. define your own modules (see Section Libraries and Modules).
  109.  
  110. If you typically load several .dbc files as part of a single program,
  111. you can combine them into one file for convenience.  The mechanism for
  112. combining .dbc files is the Unix cat utility:
  113.  
  114.    % cat foo.dbc bar.dbc baz.dbc > big.dbc
  115.    % mindy -f big.dbc
  116.  
  117.  
  118.  
  119. Syntax Errors
  120.  
  121. If there are any syntax errors in your program, mc will report them to
  122. stderr while compiling.  For example, if you had left off the closing paren
  123. in the call to puts in the above example, mc would have reported:
  124.  
  125.    hw.dylan:4: parse error at or before `;'
  126.  
  127. As the "hw.dylan:4:" is the same format the C compiler uses, gnu-emacs's
  128. compile package can parse the error messages from mc.  
  129.  
  130. Mc's error recovery isn't the best in the world.  Often, it has to
  131. completely bail, telling you only about the first few errors it found.  You
  132. have to fix what it reports and try again.
  133.  
  134. A hint to getting slightly tighter error recovery is to end all method and
  135. class definitions with "end method;" or "end class;".  For example, if you
  136. forget an "end" for a statement inside a method definition, the mc parser
  137. goes all the way to the end of the file and then reports a syntax error at
  138. the EOF position.  You don't get any more clues.  If you use "end method;",
  139. then the parser can recover at the end of the method containing the bad
  140. syntax and report the syntax error there.  This gives you a lot tighter
  141. recovery and more information in this situation.
  142.  
  143.  
  144.  
  145. Runtime Errors
  146.  
  147. Much more common than syntax errors are runtime errors.  And given the
  148. simplistic model of compilation mc uses, most semantic errors are not
  149. detected until runtime.  When Mindy hits a runtime error that is not handled
  150. via the condition system, it drops you into a debugger.  From this debugger
  151. you can look at variables, examine the stack, and invoke functions.  For
  152. example, if you had assumed that puts would be named something more
  153. reasonable, like put-string, you would have gotten the following when you
  154. tried to run your hello world program:
  155.  
  156.    % mindy -f hw.dbc
  157.  
  158.    Unbound variable: put-string
  159.  
  160.    thread [0] D   main
  161.    fp 0x1003009c: invoke-debugger({<simple-error> 0x101a24c9})
  162.    mindy> 
  163.  
  164. Typing "help" at the "mindy>" prompt will list the various commands you can
  165. use.  See the document "debug.doc" for more information.
  166.  
  167.  
  168.  
  169. Internal Lossage
  170.  
  171. Sometimes mc or Mindy will get an internal error.  When this happens, it
  172. will print a message to stderr and then abort.  This results in the process
  173. dying due to some kind of signal.  On the pmax, this signal is SIGILL, or
  174. Illegal Instruction.  When this happens, send gwydion-bugs@cs.cmu.edu a
  175. piece of mail containing the error message and information on what it was
  176. you did that triggered the problem.
  177.  
  178.  
  179.  
  180. Dylan vs. Mindy language issues
  181.  
  182. The Dylan language is still changing slightly.  Mindy implements most of the
  183. Dylan Interim Reference Manual, some features that have been accepted but
  184. not described in the DIRM, and some features we would like to see accepted
  185. before the official language specification is published.  Currently, the
  186. Mindy diverges from the DIRM in the following ways:
  187.  
  188.    Additions:
  189.      - Mindy supports multiple value binding in the =/then clauses of
  190.        for statements.  This official status of this feature is uncertain at
  191.        this time.  The format of such a clause is
  192.      (var1, var2, ...) = expr1 THEN expr2
  193.      - Mindy supports "keyed-by" clauses in for statements.  The format of
  194.        such a clause is
  195.      var KEYED-BY key IN collection
  196.        Var is bound to each element in collection, and key is bound to the
  197.        element's key value.
  198.      - Keyword parameters may have type information, and you can specify
  199.        default values with either Harlequin's proposed syntax (which uses
  200.        '= ...') or with Apple's syntax (which uses '(...)').  Mindy does not
  201.        enforce any congruence rules for keyword parameter types, so
  202.        effectively, keyword type information in generic function declarations
  203.        serves as documentation only.
  204.      - Mindy supports subclass specializers via the limited function.  A
  205.        subclass specializer causes a method to be invoked whenever the
  206.        generic function was called on a value that is the specified class or
  207.        any subclass of the specified class.  The method is never invoked on
  208.        a value that is an instance (direct or indirect) of the specified
  209.        class, only when the value is a subclass of the specified class.  The
  210.        following is an example:
  211.           define method make
  212.           (result-class :: limited(<class>, subclass-of(<my-class>)));
  213.         let x = next-method();
  214.         do-special-logging-or-something(x);
  215.         x;
  216.       end method;
  217.  
  218.    Deficiencies:
  219.      - Sealed/open, abstract/concrete, and primary keywords are parsed where
  220.        allowed, but Mindy ignores this information about your program.
  221.      - Mindy does not parse the "seal generic" from.
  222.      - Library "use" chains cannot be circular; that is, there can be no
  223.        cycles in the graph representing library "use" relationships.
  224.      - Define method does not automatically insert "#next next-method" in
  225.        parameter lists.  You have to explicitly add it yourself.
  226.      - Case and select bodies cannot be empty.
  227.      - Make(<class>, ...) is unsupported.
  228.  
  229.  
  230.  
  231. Built-in Libraries and Modules
  232.  
  233. Mindy has full support for modules and libraries.  Mindy provides two
  234. built-in libraries, Dylan and Dylan-User.  The Dylan library contains the
  235. Dylan language implementation and the following exported modules:
  236.    Dylan
  237.       This module contains the Dylan language implementation and exports all
  238.       the built-in Dylan definitions.
  239.    Extensions
  240.       This module contains useful extensions to the Dylan language (see
  241.       Section The Extensions Module).  Ultimately, there will be several,
  242.       more logically separate libraries that "extend Dylan" or provide an
  243.       application framework for users.  For now, we put any commonly used
  244.       utilities in the Extensions module.
  245.    System
  246.       This module contains an interface to operating system calls and
  247.       special, low-level functionality (see Section The System Module).
  248.    File-descriptors
  249.       This module contains an interface to most standard C system calls that
  250.       operate on file descriptors.
  251.    Threads
  252.       This module contains an interface to threads, locks, and objects that
  253.       behave similarly to cthreads.h condition variables.
  254.  
  255. The Dylan-User library is the default library in which mc compiles user
  256. code.  Mindy provides this library for user convenience when whipping up
  257. play code or small applications for which the programmer does not want to
  258. bother to create a library.  You cannot redefine the Dylan-User library.
  259. This library contains one module, Dylan-User, and you cannot redefine this
  260. module.
  261.  
  262. The Dylan language requires every library to contain a Dylan-User module,
  263. and this module must use the Dylan module from the Dylan library regardless
  264. of any user specifications.  This module provides a starting point in every
  265. library where users can begin to define modules; without an initial module
  266. in the library, you would be unable to write any code, including module
  267. definitions.  Each Dylan-user module in Mindy also automatically uses the
  268. Extensions module from the Dylan library.
  269.  
  270. Other libraries are available to Mindy users.  Later sections of this
  271. document describe these libraries.
  272.  
  273.  
  274.  
  275. Using Libraries and Modules
  276.  
  277. To compile code into a particular library use the -l switch to mc:
  278.  
  279.    % mc -lmy-lib foo.dylan
  280.  
  281. If there is no -l switch, then mc compiles the code into the Dylan-User
  282. library.  When loading a .dbc file into Mindy that was compiled into a
  283. particular library, one of the following conditions must be satisified to
  284. avoid errors:
  285.    1] The library must be the Dylan-User library.  Technically, you could
  286.       put code in the Dylan library, but do not do this.
  287.    2] You must have defined the library in a file previously loaded (see
  288.       Section Multiple Files for information on loading multiple files).
  289.    3] The first piece of code in the source file that produced the .dbc file
  290.       must be the library definition.
  291.  
  292. While loading a file, if Mindy processes a library definition that uses an
  293. undefined library, then Mindy stops loading the current file, searches for
  294. the undefined library, and loads it.  After loading the undefined library,
  295. Mindy continues loading the current file and processing the original library
  296. definition.  Mindy searches for the undefined library in the directories
  297. listed in the MINDYPATH environment variable.  If MINDYPATH is undefined,
  298. then Mindy uses the pathname $INSTALL/lib.  In each directory, Mindy looks
  299. for the file <library>.dbc where <library> is the name of the undefined
  300. library.
  301.  
  302. Mindy loads the Dylan library when it first sees a reference to it.  A
  303. reference to the Dylan library occurs when loading a file compiled to be in
  304. the Dylan library, or when loading a file with a library definition that
  305. uses the Dylan library.  Mindy loads the Dylan library by looking for the
  306. file "dylan.dbc" on MINDYPATH.
  307.  
  308. To make a single compiled file for a library which has multiple source
  309. files, compile all the files that constitute the library with the "-l"
  310. switch set to the library's name.  Then cat all the resulting .dbc files
  311. together (see Section Multiple Files), making sure the file that defines the
  312. library is first.  Then install the combined .dbc file in one of the
  313. directories in your MINDYPATH.
  314.  
  315. To compile code into a particular module, use the module: file header.
  316. Whenever a source file lacks a module: file header, mc issues a compiler
  317. warning and compiles the code into the Dylan-User module.  Note, this is the
  318. Dylan-User module of the library specified with the "-l" switch, and if
  319. there was no "-l" switch, it is the Dylan-User module of the Dylan-User
  320. library.
  321.  
  322. When loading a .dbc file into Mindy that was compiled into a particular
  323. module, one of the following conditions must be satisfied to avoid errors:
  324.    1] The module must be the Dylan-User module.
  325.    2] You must have defined the module in a file previously loaded (see
  326.       Section Multiple Files for information on loading multiple files).
  327.    3] The first code in the source file that produced the .dbc file must be
  328.       library and module definitions, and one of the module definitions must
  329.       be the module in question.
  330.  
  331.  
  332.  
  333. The Extensions Module
  334.  
  335. The Extensions module exports the following generally useful functionality:
  336.  
  337. <boolean>                                       [Class]
  338.    This class is a subclass of <object>.  There are exactly two instances of
  339.    this class, #t and #f.
  340.  
  341. <byte-vector>                                   [Class]
  342.    This class is a subclass of <vector> that can only hold integers between
  343.    0 and 255 inclusively.  This class is a temporary addition to Mindy to
  344.    support the requirement that the Streams library export a <byte-vector>
  345.    definition.  When Mindy supports limited collections, this may be defined
  346.    within the Streams library.
  347.  
  348. main (#rest arguments)                [Generic Function]
  349.    Has no methods, but is called by Mindy when it starts up.  To make a
  350.    standalone program, you define a method on main that does whatever you
  351.    want it to do.  Arguments is a sequence of strings.  There is a string in
  352.    arguments for every argument on the command line that invoked Mindy,
  353.    except all "-f" switches and the argument following each "-f" switch
  354.    (that is, the file to load) is missing.  Remember that any module that
  355.    adds a method to main must use the Extensions module from the Dylan
  356.    library.
  357.  
  358. one-of                        [Constant]
  359.    This function is useful in type expressions.  Because the union function
  360.    can only take two arguments, any type that is an enumeration of three or
  361.    more singleton values requires cascading calls to union.  Combine that
  362.    with having to wrap each value in a call to singleton, and using union
  363.    starts to create a lot of parameter list bloat.  For example, the
  364.    expression
  365.       one-of(#"foo", #"bar", #"baz")
  366.    is equivalent to
  367.       union(singleton(#"foo"), union(singleton(#"bar"), singleton("baz")))
  368.  
  369. type-or                        [Constant]
  370.    This function is useful in type expressions.  Because the union function
  371.    can only take two arguments, any type that is the union of three or more
  372.    types requires cascading calls to union.  Using type-or can be more
  373.    convenient and more clear to read.  For example, the expression
  374.       type-or(<foo>, <bar>, <baz>, <quux>)
  375.    is equivalent to
  376.       union(<foo>, union(<bar>, union(<baz>, <quux>)))
  377.  
  378.  
  379. The Extensions module exports the following <table> subclasses:
  380.  
  381. <equal-table>                    [Class]
  382.    This class is a subclass of <table> that uses the \= function to compare
  383.    keys and the equal-hash function to generate hash codes.  If you define
  384.    your own classes and \= methods specialized on those classes, then you
  385.    should define a method for the equal-hash function specialized to your
  386.    classes (see the equal-hash function description).
  387.  
  388. <value-table>                    [Abstract Class]
  389.    This class is a subclass of <table>.  Users can define subclasses of this
  390.    class and provide a method for table-protocol that is specialized to
  391.    their new subclass.  Any subclass of <value-table> must use a hash
  392.    function that never use an object's identity (that is, its location in
  393.    the heap) as a means of computing a hash id.  These tables are
  394.    specifically designed to save overhead in testing hash states and whether
  395.    the table needs to be rehashed after garbage collections.  The second
  396.    value of the hash-function should always be $permanent-hash-state.  For
  397.    example:
  398.       define class <my-table> (<value-table>)
  399.       end class;
  400.  
  401.       define method table-protocol (table :: <my-table>)
  402.         values(\=, string-hash);
  403.       end method;
  404.  
  405. The Extensions module exports the following functions to make it easier for
  406. users to use <equal-table>s and <value-table>s:
  407.  
  408. equal-hash (key :: <object>)            [Generic Function]
  409.     => (hash-id :: <integer>, hash-state)
  410.    This function returns a hash id and hash state for use with
  411.    <equal-table>s.  If you define your own classes and \= methods
  412.    specialized on those classes, then you should define a method for the
  413.    equal-hash function specialized to your classes.  Specialized methods
  414.    exist for <number>, <character>, <function>, <symbol>, and <collection>.
  415.    The method for any other <object> returns the integer 42 and
  416.    $permanent-hash-state.  This function may use an object's identity (that
  417.    is, its location in the heap) to produce a hash id.
  418.  
  419. collection-hash                    [Function]
  420.     (collection :: <collection>, key-hash-function :: <function>,
  421.      elt-hash-function :: <function>)
  422.     => (hash-id :: <integer>, hash-state)
  423.    This function hashes every element of a collection using
  424.    key-hash-function on the keys and element-hash-function on the elements.
  425.    Note, though two sequences may be equal according to the \= function,
  426.    sequence-hash and collection-hash may return different hash codes for the
  427.    sequences.
  428.  
  429. sequence-hash                    [Function]
  430.     (sequence :: <sequence>, elt-hash-function :: <function>)
  431.     => (hash-id :: <integer>, hash-state)
  432.    This function hashes every element of sequence using elt-hash-function,
  433.    merging the resulting hash codes in order.  Note, though two sequences
  434.    may be equal according to the \= function, sequence-hash and
  435.    collection-hash may return different hash codes for the sequences.
  436.  
  437. string-hash (string :: <string>)        [Function]
  438.     => (hash-id :: <integer>, hash-state)
  439.    This function calls produces hash codes for strings without using the
  440.    strings' identities.  This function is suitable for use with
  441.    <value-table>s.
  442.  
  443. value-hash (object :: <object>)            [Generic Function]
  444.     => (hash-id :: <integer>, hash-state)
  445.    This function produces hash codes for objects without using the objects'
  446.    identities.  This function is suitable for use with <value-table>s.
  447.    Mindy provides methods specialized for the following types:
  448.       <string>
  449.       <integer>
  450.       <float>
  451.       <character>
  452.       <symbol>
  453.       singleton(#t)
  454.       singleton(#f)
  455.  
  456.  
  457. The Extensions module exports the following functionality for controlling
  458. the exiting of applications:
  459.  
  460. exit (#key exit-code :: <integer> = 0)          [Function]
  461.    Causes the process to exit.  Mindy calls this function when there is
  462.    no code left to execute.
  463.  
  464. on-exit (function :: <function>)                [Function]
  465.    Arranges for the exit function to call the argument function.  The
  466.    argument function must take no required arguments.  Users may call
  467.    on-exit multiple times to install more than one function for exit to
  468.    call, but the order in which exit invokes the functions is undefined.
  469.    Calling on-exit on the same function repeatedly, installs that function
  470.    multiple times.
  471.  
  472.  
  473. The Extensions module exports the following weak-pointer functionality:
  474.  
  475. <weak-pointer>                                  [Class]
  476.    This class is a subclass of <object>.  The make method for this class
  477.    takes the keyword parameter object:.  Instances of this class refer to
  478.    the object passed to the make method as long as some other reference to
  479.    the object exists.  Whenever an instance of <weak-pointer> is the only
  480.    reference to some object, and a garbage collection occurs, then Mindy
  481.    considers the object to be garbage.  When Mindy garbage collects an
  482.    object referred to by a weak-pointer, then Mindy marks the weak-pointer
  483.    as being broken (see the weak-pointer-object function).
  484.  
  485. weak-pointer-object (wp :: <weak-pointer>)      [Function]
  486.     => (object :: <object>, broken? :: <boolean>)
  487.    Returns the object referred to by the weak-pointer and whether the
  488.    weak-pointer is broken.  A weak-pointer is broken when it contains the
  489.    only reference to some other object, and in this situation,
  490.    weak-pointer-object returns the values #f and #t.
  491.  
  492.  
  493. The Extensions module exports the following functionality that will go away
  494. as various official I/O modules get installed into Mindy:
  495.  
  496. format (control-string, #rest arguments)    [Function]
  497.    This format adheres to the format strings described in the Dylan Interim
  498.    Reference Manual with one exception.  Mindy incorrectly prints instances
  499.    of <condition> supplied to the %S directive.
  500.  
  501. print (thing)                    [Function]
  502. prin1 (thing)                    [Function]
  503.    Prints thing to stdout.  Print follows thing with a newline.  How things
  504.    are printed cannot be extended, because it is done by C code.
  505.  
  506. puts (string)                    [Function]
  507.    Prints the contents of string, which must be a <byte-string>, to stdout.
  508.  
  509. putc (char)                    [Function]
  510.    Prints the character to stdout.
  511.  
  512. getc ()                            [Function]
  513.    Read and return the next character from stdin.  Returns #f at EOF.
  514.  
  515.  
  516.  
  517. The System Module
  518.  
  519. The System module exports the following:
  520.  
  521. <buffer>                           [Class]
  522.    This class is a subclass of <vector>.  It is the built-in class in Mindy
  523.    that the Stream module supports.
  524.  
  525. copy-bytes (dst :: type_or(<buffer>, <byte-vector>, <byte-string>),
  526.             dst-offset :: <integer>,
  527.             src :: type_or(<buffer>, <byte-vector>, <byte-string>),
  528.         src-offset :: <integer>,
  529.         count :: <integer>)
  530.     => dst :: type_or(<buffer, <byte-vector>, <byte-string>)
  531.    Copies count bytes from src starting at src-offset to dst starting at
  532.    dst-offset.  This function returns dst.  This function does no bounds
  533.    checking.  Dst and Src may be the same (==) object; this function ensures
  534.    the destination portion correctly gets the bytes that were in the source
  535.    portion of the object.
  536.  
  537.  
  538.  
  539. The File-descriptor Module
  540.  
  541. A cleaner interface to most of these functions is available from the Streams
  542. library (see the document streams.txt).  You probably do not need to use
  543. this module, unless you are using fd-exec or need a very obscure file mode.
  544.  
  545. The File-descriptor module exports the following functions and constants:
  546.  
  547. fd-exec (command-line :: <string>)               [Function]
  548.     => (in-fd :: union(<integer>, singleton(#f)),
  549.         out-fd :: union(<integer>, singleton(#f)))
  550.    This function provides a facility for running programs and scripts from
  551.    within Mindy.  The command-line argument should contain the name of the
  552.    program and all of the command line arguments for that program.  This
  553.    function returns the file descriptors for the new process's standard
  554.    input and output.  If fd-exec is unable to start the process, then it
  555.    returns #f and #f.
  556.  
  557. fd-open (path :: <byte-string>, flags :: <integer>)    [Function]
  558.     => (fd :: union(singleton(#f), <integer>),
  559.         errno :: union(singleton(#f), <integer>))
  560.    This function calls the C open system call and returns the file
  561.    descriptor and #f, if successful.  If the first value is #f, then the
  562.    second value is the error number.  You can convert the error number to a
  563.    string using the fd-error-string function.
  564.  
  565. fd-close (fd :: <integer>)                   [Function]
  566.     => (win? :: <boolean>,
  567.         errno :: union(singleton(#f), <integer>))
  568.    This function calls the C close system call and returns #t and #f, if
  569.    successful.  If the first value is #f, then the second value is the error
  570.    number.  You can convert the error number to a string using the
  571.    fd-error-string function.
  572.  
  573. fd-read (fd :: <integer>, buffer :: <buffer>, offset :: <integer>,
  574.      count :: <integer>)                   [Function]
  575.     => (count :: union(singleton(#f), <integer>),
  576.         errno :: union(singleton(#f), <integer>))
  577.    This function calls the C read system call and returns the number of
  578.    bytes read and #f, if successful.  Offset is an index into buffer that is
  579.    the index at which fd-read should start writing into the buffer.  All
  580.    other arguments are the same as those described by the Unix man page.
  581.  
  582.    If the first value is #f, then the second value is the error number.  You
  583.    can convert the error number to a string using the fd-error-string
  584.    function.
  585.  
  586.    This function does no bounds checking.
  587.  
  588. fd-write (fd :: <integer>, buffer :: <buffer>,
  589.           offset :: <integer>, count :: <integer>)     [Function]
  590.     => (count :: union(singleton(#f), <integer>),
  591.         errno :: union(singleton(#f), <integer>))
  592.    This function calls the C write system call and returns the number of
  593.    bytes written and #f, if successful.  Offset is an index into buffer that
  594.    is the index at which fd-write should start reading from the buffer.  All
  595.    other arguments are the same as those described by the Unix man page.
  596.  
  597.    If the first value is #f, then the second value is the error number.  You
  598.    can convert the error number to a string using the fd-error-string
  599.    function.
  600.  
  601.    This function does no bounds checking.
  602.  
  603. fd-input-available? (fd :: <integer>)               [Function]
  604.     => (input? :: <boolean>,
  605.         errno :: union(singleton(#f), <integer>))
  606.    This function returns whether there is any input available on the file
  607.    descriptor.  The second return value is #f if fd-input-available? could
  608.    determine whether input was available, but if there is an error, the
  609.    second return value is the error number.  You can convert the error
  610.    number to a string using the fd-error-string function.
  611.  
  612. fd-sync-output (fd :: <integer>)               [Function]
  613.     => (win? :: <boolean>,
  614.         errno :: union(singleton(#f), <integer>))
  615.    This function calls the C fsync system call and returns #t and #f, if
  616.    successful.  If the first value is #f, then the second value is the error
  617.    number.  You can convert the error number to a string using the
  618.    fd-error-string function.
  619.  
  620. fd-seek (fd :: <integer>, offset :: <integer>,
  621.          whence :: <integer>)                   [Function]
  622.     => (new-pos :: union(singleton(#f), <integer>), 
  623.         errno :: union(singleton(#f), <integer>))
  624.    This function calls the C lseek system call and returns the new absolute
  625.    position in the file and #f, if successful.  If the first value is #f,
  626.    then the second value is the error number.  You can convert the error
  627.    number to a string using the fd-error-string function.
  628.  
  629. fd-error-string (errno :: <integer>)               [Function]
  630.     => msg :: union(singleton(#f), <byte-string>)
  631.    This function calls the C strerror system call and returns the string
  632.    that describes the given error number.  If the error number is unknown,
  633.    then fd-error-string return #f.
  634.  
  635. L_SET                               [Constant]
  636. L_INCR                               [Constant]
  637. L_XTND                               [Constant]
  638. FNDELAY                               [Constant]
  639. FAPPEND                               [Constant]
  640. FCREAT                               [Constant]
  641. FTRUNC                               [Constant]
  642. FEXCL                               [Constant]
  643. O_RDONLY                           [Constant]
  644. O_WRONLY                           [Constant]
  645. O_RDWR                               [Constant]
  646. O_NDELAY                           [Constant]
  647. O_APPEND                           [Constant]
  648. O_CREAT                               [Constant]
  649. O_TRUNC                               [Constant]
  650. O_EXCL                               [Constant]
  651. ENOENT                               [Constant]
  652. EIO                               [Constant]
  653. ENXIO                               [Constant]
  654. EACCES                               [Constant]
  655. EFAULT                               [Constant]
  656. EEXIST                               [Constant]
  657. ENOTDIR                               [Constant]
  658. EISDIR                               [Constant]
  659. EINVAL                               [Constant]
  660. ENFILE                               [Constant]
  661. EMFILE                               [Constant]
  662. ETXTBSY                               [Constant]
  663. ENOSPC                               [Constant]
  664. EROFS                               [Constant]
  665. EOPNOTSUPP                           [Constant]
  666. ELOOP                               [Constant]
  667. ENAMETOOLONG                           [Constant]
  668. EDQUOT                               [Constant]
  669. EBADF                               [Constant]
  670. EINTR                               [Constant]
  671. EWOULDBLOCK                           [Constant]
  672. EPIPE                               [Constant]
  673. EFBIG                               [Constant]
  674.    These constants are the same constants from the standard C libraries,
  675.    file.h and errno.h.  All the constants users need to call the functions
  676.    in the File-descriptor module, or test the return values of these
  677.    functions, should be exported from this module.
  678.  
  679.  
  680.  
  681. The Threads Module
  682.  
  683. This module is in the Dylan library and exports an interface to <thread>s,
  684. <lock>s, and <event>s (objects on which threads can wait until a signalling
  685. thread indicates the events have occurred).
  686.  
  687. <thread>                           [Class]
  688.    This class is a subclass of <object>.  Instances of this class are the
  689.    handles by which programs manipulate threads.
  690.  
  691. spawn-thread (debug-name :: <byte-string>,           [Function]
  692.               init-function :: <function>)
  693.     => thread :: <thread>
  694.    Spawns a concurrent asynchronous thread and invokes init-function in that
  695.    thread.  The dynamic context of the thread is the same as if it were the
  696.    main thread of a program at the beginning of the program's execution.
  697.  
  698. kill-thread (thread :: <thread>)               [Function]
  699.     => <thread>
  700.    Kills thread immediately.  After calling this function, the argument
  701.    thread never executes again.
  702.  
  703. <lock>                               [Abstract Class]
  704.    This class is a subclass of <object>.  Instances of this class provide
  705.    logical locks.  A lock is locked when a thread successfully "grabs" a
  706.    lock, and we say the thread "holds" the lock.  Holding a lock in no way
  707.    prohibits access to a resource.  It is purely the convention of various
  708.    threads to access a shared resource only after successfully grabbing a
  709.    lock.  If <lock> is passed to make, make returns a <spinlock>.
  710.  
  711.  
  712. <spinlock>                           [Sealed Class]
  713.    This class is a subclass of <lock>.  Instances of this class provide a
  714.    single-locking model.  
  715.  
  716.    Whenever a <spinlock> is unlocked, any thread may grab it.  Whenever a
  717.    <spinlock> is locked, any thread that tries to grab it will block.
  718.    Whenever a <spinlock> is locked, any thread may release it.
  719.  
  720.    <spinlock>s are designed to be held for a very short period of time,
  721.    several machine instructions at most.  Threads should only hold a
  722.    <spinlock> for a very short period of time because other threads that
  723.    are waiting for the lock are blocked and could be wasting CPU cycles by
  724.    busy looping; that is, waiting for a <spinlock> does not necessarily use
  725.    anything as heavy weight as a system call to sleep the thread waiting for
  726.    the lock.  If only a couple threads are sharing a resource, it may be
  727.    more efficient to actually hold a <spinlock> for a moderate amount of
  728.    time while performing a high-level operation, rather than use a lock to
  729.    build a more heavy-weight mutual exclusion mechanism (such as a
  730.    semaphore) to isolate access to the shared resource.
  731.  
  732.    Unlocking a <spinlock> when it is already unlocked signals an error.
  733.  
  734. <multilock>                           [Sealed Class]
  735.    This class is a subclass of <lock>.  Instances of this class provide a
  736.    multilocking model.  
  737.  
  738.    Whenever a <multilock> is unlocked, any thread may grab it.  A thread
  739.    that holds a <multilock> may grab the lock repeatedly without releasing
  740.    the lock.  Each grab effectively increments a counter, and each release
  741.    effectively decrements a counter.  A <multilock> is available to be
  742.    grabbed by any thread when the counter returns to zero; therefore, a
  743.    thread must release the lock for each grabbing of the lock.  This
  744.    behavior is useful for implementing a high-level operation that needs to
  745.    isolate access to a resource while calling a few lower-level operations
  746.    that lock the resource; in this way, the high-level operation effectively
  747.    calls all the lower-level operations atomically with no other threads
  748.    affecting the state of the resource between the calls.
  749.  
  750.    Whenever a <multilock> is locked, only the thread that holds the lock may
  751.    release it.
  752.  
  753.    <multilock>s are designed to be held for as long as a thread requires.
  754.    When other threads call the grab-lock function and block because a
  755.    <multilock> is locked, the other threads are guaranteed to sleep until
  756.    the lock is available.
  757.  
  758.    Unlocking a <multilock> when it is already unlocked signals an error.
  759.  
  760. <semaphore>                           [Sealed Class]
  761.    This class is a subclass of <lock>.  Instances of this class provide a
  762.    single-locking model.
  763.  
  764.    Whenever a <semaphore> is unlocked, any thread may grab it.  Whenever a
  765.    <semaphore> is locked, any thread that tries to grab it will block.
  766.    Whenever a <semaphore> is locked, any thread may release it.
  767.  
  768.    <semaphore>s are designed to be held for as long as a thread requires.
  769.    When other threads call the grab-lock function and block because a
  770.    <semaphore> is locked, the other threads are guaranteed to sleep until
  771.    the lock is available.
  772.  
  773.    Unlocking a <semaphore> when it is already unlocked signals an error.
  774.  
  775. locked? (lock :: <lock>)                   [Function]
  776.     => locked? :: <boolean>
  777.    Returns whether the lock is held by any thread.
  778.  
  779. grab-lock (lock :: <lock>)                   [Generic Function]
  780.     => meaningless :: singleton(#f)
  781.    Returns after successfully grabbing the lock.  If the lock is not
  782.    immediately available, this function waits for the lock to become
  783.    available.
  784.  
  785. grab-lock (lock :: <spinlock>)                   [G.F. Method]
  786.     => meaningless :: singleton(#f)
  787.    Returns after successfully grabbing the lock.  This method can only grab
  788.    lock when it is unlocked.  When the lock is held, this method may
  789.    busy-loop until the lock is unlocked.
  790.  
  791. grab-lock (lock :: <semaphore>)                   [G.F. Method]
  792.     => meaningless :: singleton(#f)
  793.    Returns after successfully grabbing the lock.  This method can only grab
  794.    lock when it is unlocked.  When the lock is held, this method puts the
  795.    calling thread to sleep until until the lock is available.
  796.  
  797. grab-lock (lock :: <multilock>)                   [G.F. Method]
  798.     => meaningless :: singleton(#f)
  799.    Returns after successfully grabbing the lock.  A single thread may
  800.    successfully call this method repeatedly, but the thread must call
  801.    release-lock once for each call to grab-lock.  If the thread calls
  802.    release-lock fewer times than grab-lock, the lock remains locked, and any
  803.    threads waiting for the lock will continue to wait.  When a thread that
  804.    does not hold the lock calls this method, the method puts the calling
  805.    thread to sleep until the lock is available.
  806.  
  807. release-lock (lock :: <lock>)                   [Generic Function]
  808.     => meaningless :: singleton(#f)
  809.    Releases the lock.  If lock is unlocked, this function signals an error.
  810.  
  811. release-lock (lock :: union(<spinlock>, <semaphore>)   [G.F. Method]
  812.     => meaningless :: singleton(#f)
  813.    Releases the lock.  If lock is unlocked, this function signals an error.
  814.    Any thread may unlock a <spinlock> or <semaphore>, regardless of whether
  815.    it is the thread that successfully grabbed the lock.
  816.  
  817. release-lock (lock :: <multilock>)               [G.F. Method]
  818.     => meaningless :: singleton(#f)
  819.    Releases the lock.  If lock is unlocked, this function signals an error.
  820.    Only the thread that holds lock may call this function, and if another
  821.    thread tries to release the lock, this method signals an error.  When
  822.    this function returns, lock may still be locked.  A thread that has
  823.    repeatedly grabbed a <multilock> must call release-lock once for each
  824.    call to grab-lock.
  825.  
  826. <event>                               [Class]
  827.    This class is a subclass of <object>.  Threads use events to block
  828.    without busy looping and to communicate to other threads that they should
  829.    wake up.
  830.  
  831. wait-for-event (event :: <event>, lock :: <lock>)      [Generic Function]
  832.     => meaningless :: singleton(#f)
  833.    Releases the lock and puts the calling thread to sleep until some other
  834.    thread signals event.  After this function returns, the lock is unheld,
  835.    and the calling thread must try to grab the lock before accessing any
  836.    shared resources.  Due to implementation details, this function may
  837.    return even when the lock is unavailable, or the event has not truly
  838.    occurred; because of this, programs need to loop over wait-for-event and
  839.    grab-lock, testing that the event actually occurred.  Methods exist for
  840.    both <spinlock>s and <semaphore>s.
  841.  
  842. signal-event (event :: <event>)                   [Function]
  843.     => meaningless :: singleton(#f)
  844.    Signals that the event occurred, indicating that Mindy should wake up a
  845.    thread that is waiting on this event.
  846.  
  847. broadcast-event(<event>)                   [Function]
  848.     => meaningless :: singleton(#f)
  849.    Signals that the event occurred and causes Mindy to wake up every thread
  850.    that is waiting on this event.
  851.  
  852.  
  853.  
  854. Examples of Using the Thread Module
  855.  
  856. The following code shows how to use locks and events to isolate access to a
  857. queue:
  858.  
  859.    // This example shows two routines, get-queue and release-queue.  Code
  860.    // that accesses the queue should call get-queue before doing so and call
  861.    // release-queue when done.  Any code failing to isolate access to the
  862.    // queue in this way has undefined behavior and is incorrectly written.
  863.    //
  864.  
  865.    // This variable is #t if and only if the queue is generally available.
  866.    //
  867.    define variable queue-available? = #t;
  868.  
  869.    // This constant holds an event object used to signal when the queue
  870.    // becomes generally available again.
  871.    //
  872.    define constant queue-available = make(<event>);
  873.  
  874.    // This constant holds a lock object used to isolate access to
  875.    // queue-available? for testing and setting purposes.
  876.    //
  877.    define constant queue-lock = make(<lock>);
  878.  
  879.    // When this function returns, the caller has exclusive access to the
  880.    // queue.  If necessary, this function waits for the queue to become
  881.    // available, but it does not busy loop.  This function returns #f as
  882.    // a meaningless return value.
  883.    //
  884.    define method get-queue ()
  885.      grab-lock(queue-lock);
  886.      while (~ queue-available?)
  887.        wait-for-event(queue-available, queue-lock);
  888.        grab-lock(queue-lock)
  889.      end;
  890.      queue-available? := #f;
  891.      lock-release(queue-lock);
  892.      #f;
  893.    end;
  894.  
  895.    // This function releases the queue and signals that it is released so
  896.    // that someone waiting on the queue will be woken up.  This function
  897.    // returns #f as a meaningless return value.
  898.    //
  899.    define method release-queue ()
  900.      grab-lock(queue-lock);
  901.      queue-available? := #t
  902.      release-lock(queue-lock);
  903.      signal-event(queue-available);
  904.      #f;
  905.    end;
  906.  
  907. The following example shows how to use a lock to isolate queue access in a
  908. different way than the previous example:
  909.  
  910.    // This constant holds an event object used to signal when an element
  911.    // exists in the queue.
  912.    //
  913.    define constant something-available = make(<event>);
  914.  
  915.    // This constant holds a lock that is held whenever a thread is accessing
  916.    // queue.
  917.    //
  918.    define constant lock = make(<lock>);
  919.  
  920.    // This constant holds a queue object.
  921.    //
  922.    define constant queue = make(<deque>);
  923.  
  924.    // This function returns an element from queue.  If no element is
  925.    // immediately available, then this function blocks until it can return
  926.    // an element.  This function assumes only one or two other threads are
  927.    // ever waiting for the queue, and it assumes pop is a fast high-level
  928.    // operation.
  929.    //
  930.    define method get-something()
  931.      grab-lock(lock);
  932.      while (empty?(queue)))
  933.        wait-for-event(something-available, lock);
  934.        grab-lock(lock);
  935.      end;
  936.      let result = pop(queue);
  937.      lock-release(lock);
  938.      result;
  939.    end;
  940.  
  941.    // This function adds thing to queue.  It assumes only one or two other
  942.    // threads are ever waiting for the queue, and it assumes push is a fast
  943.    // high-level operation.
  944.    //
  945.    define method put-something(thing)
  946.      grab-lock(lock);
  947.      push(queue, thing);
  948.      release-lock(lock);
  949.      signal-event(something-available);
  950.    end;
  951.  
  952.  
  953.  
  954. Streams Library
  955.  
  956. There is a Streams library that adheres to the Gwydion streams
  957. specification.  For documentation on the stream specification, see the
  958. following:
  959.    $INSTALL/doc/streams.{ps,txt}
  960.  
  961. The Streams library exports two modules, Streams and Standard-io.  The
  962. Streams module exports all identifiers from the streams specification.  The
  963. Streams module also exports <fd-stream>:
  964.  
  965. <fd-stream>                           [Class]
  966.    This class is a subclass of <stream>.  These streams are based on C file
  967.    descriptors, and they do not adhere to the Random Access Protocol
  968.    described in the Gwydion streams specification.  The make method accepts
  969.    the following keywords:
  970.       direction:
  971.          This keyword is optional and defaults to #"input".  When supplied,
  972.      it must be either #"input" or #"output".
  973.       fd:
  974.          This keyword is required and should be an open file-descriptor.
  975.       size:
  976.          This keyword is optional and is the size of the buffer.  See the
  977.      streams specification for details.
  978.  
  979. The Standard-io module exports the following:
  980.  
  981. *standard-input*                       [Constant]
  982. *standard-output*                       [Constant]
  983. *standard-error*                       [Constant]
  984.    These have the following values respectively:
  985.       make(<fd-stream>, fd: 0)
  986.       make(<fd-stream>, fd: 1, direction: #"output")
  987.       make(<fd-stream>, fd: 2, direction: #"output")
  988.  
  989.  
  990.  
  991. Implementation Choices
  992.  
  993. The error method specialized on <byte-string> applies the format function to
  994. the arguments passed to error.  See Section The Extensions Module for the
  995. details of format.
  996.  
  997. Rest arguments in Mindy are <sequence>s.  You cannot use any functions on
  998. the rest argument that assumes the collection is an instance of any class
  999. more specific than <sequence>; for example, you cannot use the head or tail
  1000. functions because they operate on instances of <pair>.
  1001.  
  1002.  
  1003.  
  1004. Copyright and terms of use
  1005.  
  1006. Copyright (c) 1994  Carnegie Mellon University
  1007. All rights reserved.  
  1008.  
  1009. Use and copying of this software and preparation of derivative works based on
  1010. this software are permitted, including commercial use, provided that the
  1011. following conditions are observed:
  1012.  
  1013. 1. This copyright notice must be retained in full on any copies and on
  1014.    appropriate parts of any derivative works.
  1015. 2. Documentation (paper or online) accompanying any system that incorporates
  1016.    this software, or any part of it, must acknowledge the contribution of the
  1017.    Gwydion Project at Carnegie Mellon University.
  1018.  
  1019. This software is made available "as is".  Neither the authors nor Carnegie
  1020. Mellon University make any warranty about the software, its performance, or
  1021. its conformity to any specification.
  1022.  
  1023. Bug reports, questions, comments, and suggestions should be sent by E-mail to
  1024. the Internet address "gwydion-bugs@cs.cmu.edu".
  1025.